// 定义字符串
let str1: string = "hello";
let str2: string;
str2 = "hi";

// 自动类型推断
let str3 = "abc";
// str3 = 5;

// 定义数字
let num1: number = 5;
num1 = 7;

// 定义布尔值
let done: boolean = true;
done = false;

// 定义undefined
let udf: undefined = undefined;

// 定义null
let nl: null = null;

// 联合类型
let a: number | boolean | string = 3;
a = true;
a = "hi";

// const list: string | null = localStorage.getItem("list");
// list && JSON.parse(list);

// any表示任何类型
let arr1: any = [1, 2, 3, 4];
arr1 = 3;
arr1 = true;

// 数组类型
let arr2: number[] = [1, 2, 3, 4, 5];
let arr3: Array<string> = ["1", "2", "3"];
let arr4: (number | boolean)[] = [1, 2, true];
let arr5: Array<number | boolean> = [1, 2, true];
let arr6: Array<number | boolean | any> = [1, 2, true, { a: 3 }];
let arr7: Array<any> = [1, 2, true, { a: 3 }];
let arr8: any = [1, 2, true, { a: 3 }];

// 元组类型
// 元组还是一种特殊的数组，它规定了数组的长度，和每一项的类型
let arr9: [number, string] = [1, "2"];
// console.log(arr9[1]); // 元组不能进行越界访问

// 对象类型
interface ObjType {
  name: string;
  age: number | string;
  // 可选属性
  sex?: number;
  // 索引签名
  [propname: string]: any;
}
let obj: ObjType = {
  name: "pengshao",
  age: "20",
  a: 3,
  b() {},
  c: true,
};
obj.sex = 1;

interface ItemType {
  name: string;
  id: number;
  children?: ItemType[];
}
const arr10: ItemType[] = [
  {
    name: "zhangsan",
    id: 1,
    children: [
      {
        name: "zhangsi",
        id: 11,
      },
      {
        name: "zhangwu",
        id: 12,
      },
    ],
  },
  {
    name: "lisi",
    id: 2,
  },
];

// 枚举类型 enum
// 类似于对象，可以通过key找value，也可以通过value找key
enum Color {
  Red = 3,
  Green = 5,
  Blue = 7,
}
// let g: Color = Color.Green;
// console.log(g);
let colorname: string = Color[5];
// console.log(colorname);

// 函数
// 函数的参数要加类型
// 函数的类型是返回值的类型
// 可选参数要放在最后
function add(x: number, y?: string): string {
  return y ? x + y : x + "";
}
add(3, "4");
add(3);

const add2: (x: number, y: number) => number = function (
  x: number,
  y: number
): number {
  return x + y;
};

// void类型，用于函数，没有返回值的时候用
const add3 = (x: number, y: number): void => {
  console.log(x, y);
};

// never类型，表示从不，用于函数,报错的时候，死循环的时候
// const add4 = (): never => {
//   throw new Error()
// }
// const add5 = (): never => {
//   while (true) {}
// }

// 泛型类型
function add6<T>(x: T, y: T) {
  return `${x}${y}`;
}
add6<string>("3", "4");

// const count = ref<number>(3);

// class类型
interface ObjType2 {
  name: string;
}
class Animal {
  constructor(obj: ObjType2) {
    this.name = obj.name;
  }
  name: string = "cat";
  sayName(): string {
    return this.name;
  }
}
// 类的继承
class Cat extends Animal {
  // constructor是类里面的一个特殊的函数
  // 它在这个构造函数被实例化的时候调用
  constructor(obj: ObjType2) {
    // super函数调用，触发了父类的constructor
    super(obj);
    // console.log(obj);
  }
}
// 类的实例化
const cat = new Cat({
  name: "dog",
});

// console.log(cat.name);
// console.log(cat.sayName());
console.log(cat.name); // dog
